let code = require('../../../constant/code');
let scheduler = require('pomelo-scheduler');
let RoomFrame = require('../../../gameComponent/roomFrame');
let utils = require('../../../util/utils');
let enumeration = require('../../../constant/enumeration');
let commonDao = require('../../../dao/commonDao');
let userDao = require('../../../dao/userDao');
let unionManager = require('./unionManager');
let logger = require('pomelo-logger').getLogger("logic");
let gameConfig = require('../../../gameComponent/gameConfig');
let moment = require('moment');
let redisService = require('../../../services/redisService');
let logerService = require('../../../services/logServices');
let gameDataServices = require('../../../services/gameDataServices');
let userInfoServices = require('../../../services/userInfoServices');
let goldGame = require('../../../../config/goldGame');

class union {
    constructor(unionID) {
        this.unionID = unionID;
        this.roomList = {};
        this.activeTime = Date.now();
        this.unionData = null;
        this.pendingRoom = {};//再来一局预开房间
    }

    // 初始化
    async init() {

        // 特殊unionID 1，表示普通创建房间，并入到特殊联盟中进行统一管理
        if (this.unionID !== 1) {
            // 缓存数据
            this.unionData = await commonDao.findOneData("unionModel", { unionID: this.unionID });
            if (this.unionData) {
                //判断是否有百人房间
                this.autoCreateRoom(6);
            }
        }
    }

    async onDestroy() {
        for (let roomID in this.roomList) {
            let room = this.roomList[roomID];
            if (!room) return;
            await room.dismissRoom(enumeration.gameRoomDismissReason.UNION_OWNER_DISMISS).catch(e => { logger.error(e.stack) });
        }
    }

    /****************************** 俱乐部信息 ***************************/
    // 获取俱乐部信息
    getUnionInfo(uid) {
        this.activeTime = Date.now();
        if (this.unionData) {
            let unionData = utils.clone(this.unionData);
            // if (uid !== this.unionData.ownerUid) {
            //     delete unionData['joinRequestList'];
            // }
            return unionData;
        } else {
            return null;
        }

    }

    // 获取房间列表
    getUnionRoomList() {
        this.activeTime = Date.now();
        let list = [];

        let fullTableCount = 0;
        for (let key in this.roomList) {
            if (this.roomList.hasOwnProperty(key)) {

                if (!this.roomList[key]) {
                    delete this.roomList[key];
                    continue;
                }
                let roomInfo = this.roomList[key].getRoomInfo();
                if (!!roomInfo && !roomInfo.isGameEnd) {
                    list.push(this.roomList[key].getRoomInfo());
                }
                if (roomInfo && roomInfo.gameStarted) {
                    fullTableCount += 1;
                }
            }
        }
        list.sort((a, b) => { return b.playerCount - a.playerCount });
        let haveUserCount = (list.filter(item => item.playerCount > 0)).length;
        let totalRoomCount = list.length;
        if (totalRoomCount < 6) {
            //如果不够6个房间 自动生成6个
            let curCount = 6 - totalRoomCount;
            this.autoCreateRoom(curCount);
        } else {
            //如果已经有6个机以上的房间
            if (totalRoomCount == haveUserCount) {
                //满了开两个
                this.autoCreateRoom(2);
            } else if (totalRoomCount - haveUserCount >= 2) {
                // 空房间数量
                let minRoomCount = 6;
                if (haveUserCount >= 6) {
                    minRoomCount = haveUserCount % 2 == 0 ? haveUserCount + 2 : haveUserCount + 1;
                }
                let curList = list.slice();
                minRoomCount = minRoomCount > totalRoomCount ? totalRoomCount : minRoomCount;
                list = curList.splice(0, minRoomCount);
                //剩下的解散房间
                for (let i = 0; i < curList.length; i++) {
                    let roomID = curList[i].roomID;
                    this.dismissRoom(roomID);
                }
            }
        }
        return list;
    }


    //自动创建房间
    async autoCreateRoom(count) {

        let roomList = this.unionData.roomRuleList;
        let userData = await userDao.getUserDataByUid(this.unionData.ownerUid);
        let userInfo = userInfoServices.buildGameRoomUserInfo(userData);
        for (let i = 0; i < roomList.length; i++) {
            let ruleID = roomList[i].id;
            let gameRule = JSON.parse(roomList[i].gameRule);
            for (let i = 0; i < count; i++) {
                //预创建房间
                await this.createRoomAuto(ruleID, gameRule, userInfo);
            }
        }
    }


    // 获取创建者
    getOwnerUid() {
        if (!this.unionData) return 0;
        else return this.unionData.ownerUid;
    }


    //更新联盟信息
    async updateUnionInfo(updateData) {

        if (!this.unionData) {
            throw new Error(code.FAIL);
        }
        await commonDao.updateData('unionModel', { unionID: this.unionID }, updateData);
        this.unionData = await commonDao.findOneData("unionModel", { unionID: this.unionID });
        return code.OK;
    }



    // 更新通知
    async updateUnionNotice(notice) {
        if (!this.unionData) {
            throw new Error(code.FAIL);
        }
        if (this.unionData.notice === notice) return;
        await commonDao.updateData('unionModel', { unionID: this.unionID }, { notice: notice });
        this.unionData.notice = notice;
    }

    // 转移联盟
    async transferUnion(transferUid) {
        if (!this.unionData) {
            throw new Error(code.FAIL);
        }
        let ownerUser = await commonDao.findOneData("userModel", { uid: transferUid });
        await commonDao.updateData('unionModel', { unionID: this.unionID }, { ownerUid: transferUid, ownerNickname: ownerUser.nickname, ownerAvatar: ownerUser.avatar });
        this.unionData.ownerUid = transferUid;
    }

    // 修改联盟名字
    async updateUnionName(unionName) {
        if (!this.unionData) {
            throw new Error(code.FAIL);
        }
        if (this.unionData.unionName === unionName) return;
        await commonDao.updateData('unionModel', { unionID: this.unionID }, { unionName: unionName });
        this.unionData.unionName = unionName;
    }

    // 修改联盟抽税模式
    async UpdatePumpWaterPattern(pumpWaterPattern) {
        if (!this.unionData) {
            throw new Error(code.FAIL);
        }
        if (this.unionData.pumpWaterPattern === pumpWaterPattern) return;
        //if (pumpWaterPattern <= 0) return;
        await commonDao.updateData('unionModel', { unionID: this.unionID }, { pumpWaterPattern: pumpWaterPattern });
        this.unionData.pumpWaterPattern = pumpWaterPattern;
    }

    // 修改联盟服务费
    async updateUnionServerScore(serverScore) {
        if (!this.unionData) {
            throw new Error(code.FAIL);
        }
        if (this.unionData.serverScore === serverScore) return;
        if (serverScore <= 0) return;
        await commonDao.updateData('unionModel', { unionID: this.unionID }, { serverScore: serverScore });
        this.unionData.serverScore = serverScore;
    }
    // 设置联盟牌桌排序
    async updateUnionTableSort(unionID, tableSort) {
        if (!this.unionData) {
            throw new Error(code.FAIL);
        }
        await commonDao.updateData('unionModel', { unionID: unionID }, { tableSort: tableSort });
        this.unionData.tableSort = tableSort;
    };

    // 设置联盟牌桌颜色
    async updateUnionTableColor(unionID, tableColor, unionBg, tableStyle) {
        if (!this.unionData) {
            throw new Error(code.FAIL);
        }
        await commonDao.updateData('unionModel', {
            unionID: unionID
        }, {
            tableColor: tableColor,
            unionBg: unionBg,
            tableStyle: tableStyle
        });
        this.unionData.tableColor = tableColor;
        this.unionData.unionBg = unionBg;
        this.unionData.tableStyle = tableStyle;

    };

    // 删除联盟
    async deleteUnion() {
        if (!this.unionData) {
            throw new Error(code.FAIL);
        }
        await commonDao.updateData('unionModel', { unionID: this.unionID }, { isDel: true });
        await commonDao.updateAllData("userModel", { "unionInfo.unionID": this.unionID }, { $pull: { unionInfo: { unionID: this.unionID } } });
        this.unionData.isDel = true;
    }

    // 修改公告开关
    async updatePartnerNoticeSwitch(isOpen) {
        if (!this.unionData) {
            throw new Error(code.FAIL);
        }
        if (this.unionData.noticeSwitch === isOpen) return;
        await commonDao.updateData('unionModel', { unionID: this.unionID }, { noticeSwitch: isOpen });
        this.unionData.unionName = unionName;
    }

    async updateHongBaoSetting(status, startTime, endTime, count, totalScore) {
        if (!this.unionData) {
            return code.FAIL;
        }
        let hongBaoInfo = {
            status: status,
            startTime: startTime,
            endTime: endTime,
            count: count,
            totalScore: totalScore
        };
        let updateInfo = {
            hongBaoInfo: hongBaoInfo
        };
        // 关闭红包时，清除所有红包
        if (!status) {
            this.unionData.hongBaoScoreList = [];
            this.unionData.hongBaoUidList = [];
            updateInfo.hongBaoScoreList = [];
            updateInfo.hongBaoUidList = [];
        } else {
            // 红包数为零时重新分派红包
            if (this.unionData.hongBaoScoreList.length === 0) {
                // 设置红包分数
                this.unionData.hongBaoScoreList = utils.randomRedPacket(hongBaoInfo.totalScore, hongBaoInfo.count);
                this.unionData.hongBaoUidList = [];
                updateInfo.hongBaoUidList = this.unionData.hongBaoScoreList;
                updateInfo.hongBaoUidList = [];
            } else {
                return code.CAN_NOT_CREATE_NEW_HONG_BAO;
            }
        }
        await commonDao.updateData('unionModel', { unionID: this.unionID }, updateInfo);
        this.unionData.hongBaoInfo = hongBaoInfo;
        return code.OK;
    }

    async getHongBao(uid) {
        // 检查当前是否可以领取
        if (!this.unionData) {
            logger.error("getHongBao", "unionData not exist");
            return -1;
        }
        let hongBaoInfo = this.unionData.hongBaoInfo;
        if (!hongBaoInfo || !hongBaoInfo.status) return -1;
        let date = new Date();
        let time = date.getHours();
        if (time < hongBaoInfo.startTime || time >= hongBaoInfo.endTime) return -1;
        if (hongBaoInfo.totalScore <= 0 || hongBaoInfo.count <= 0) return -1;
        // 用户领取
        if (this.unionData.hongBaoScoreList.length === 0) return 0;
        if (this.unionData.hongBaoUidList.indexOf(uid) !== -1) return 0;
        let score = this.unionData.hongBaoScoreList.shift();
        this.unionData.hongBaoUidList.push(uid);
        // 记录用户分数变化
        // 更新用户
        let saveData = {
            $inc: {
                "unionInfo.$.score": score
            }
        };
        let newUserData = await userDao.updateUserData({ uid: uid, "unionInfo.unionID": this.unionID }, saveData);

        // 存储分数变化记录
        let newUnionInfo = newUserData.unionInfo.find(function (e) {
            return e.unionID === this.unionID;
        }.bind(this));
        if (!newUnionInfo) return -1;
        let scoreChangeRecord = {
            uid: uid,
            nickname: newUserData.nickname,
            unionID: this.unionID,
            changeCount: score,
            leftCount: newUnionInfo.score,
            leftSafeBoxCount: newUnionInfo.safeScore,
            changeType: enumeration.scoreChangeType.NONE,
            describe: "领取红包:" + score,
            createTime: Date.now()
        };

        commonDao.updateData('unionModel', { unionID: this.unionID }, { hongBaoScoreList: this.unionData.hongBaoScoreList, $push: { hongBaoUidList: uid } }).catch(e => { logger.error(e.stack) });

        return { score: score, updateUserData: { unionInfo: newUserData.unionInfo } };
    }

    // 修改营业状态
    async updateOpeningStatus(isOpen) {
        if (!this.unionData) {
            throw new Error(code.FAIL);
        }
        if (this.unionData.opening === isOpen) return;
        await commonDao.updateData('unionModel', { unionID: this.unionID }, { opening: isOpen });
        this.unionData.opening = isOpen;
    }

    async updateLotteryStatus(isOpen) {
        if (!this.unionData) {
            throw new Error(code.FAIL);
        }
        if (!this.unionData.resultLotteryInfo) this.unionData.resultLotteryInfo = {};
        if (this.unionData.resultLotteryInfo.status === isOpen) return;
        this.unionData.resultLotteryInfo.status = isOpen;
        await commonDao.updateData('unionModel', { unionID: this.unionID }, { resultLotteryInfo: this.unionData.resultLotteryInfo });

        // 更新所有房间状态
        for (let key in this.roomList) {
            if (this.roomList.hasOwnProperty(key)) {
                let room = this.roomList[key];
                room.updateLotteryInfo(this.unionData.resultLotteryInfo);
            }
        }
    }

    getLotteryStatus() {
        if (!this.unionData) return {};
        return this.unionData.resultLotteryInfo || {};
    }

    // 更新联盟状态
    async updateStatus() {
        if (!this.unionData) {
            throw new Error(code.FAIL);
        }
        let unionData = await commonDao.findOneData('unionModel', { unionID: this.unionID });
        if (!unionData) {
            throw new Error(code.FAIL);
        }
        this.unionData.showRank = !!unionData.showRank;
        this.unionData.showUnionActive = !!unionData.showUnionActive;
        this.unionData.showSingleRank = !!unionData.showSingleRank;
        this.unionData.forbidInvite = !!unionData.forbidInvite;
        this.unionData.forbidGive = !!unionData.forbidGive;
    }

    // 添加房间规则
    async addRoomRuleList(roomRule, ruleName, gameType) {

        if (!this.unionData) {
            throw new Error(code.FAIL);
        }

        let curRuleList = this.unionData.roomRuleList;
        if (curRuleList && curRuleList.length > 0) {
            return code.UNION_COUNT_REACH_LIMIT;
        }

        let createTime = gameType + moment().format("x");
        let info = {
            gameRule: JSON.stringify(roomRule),
            ruleName: ruleName,
            gameType: gameType,
            createTime: createTime,
        };
        let data = await commonDao.findOneAndUpdate('unionModel', { unionID: this.unionID }, { $push: { roomRuleList: info } });
        let roomRuleList = [];
        for (let i = 0; i < data.roomRuleList.length; ++i) {
            roomRuleList.push(data.roomRuleList[i]._doc);
        }
        this.unionData.roomRuleList = roomRuleList;
        let curAddRule = data.roomRuleList.find(item => item.createTime == createTime);
        return code.OK;
    }

    // 添加房间规则
    async updateRoomRuleList(_id, roomRule, ruleName, gameType) {
        if (!this.unionData) {
            throw new Error(code.FAIL);
        }
        roomRule._id = _id;
        let info = {
            "roomRuleList.$.gameRule": JSON.stringify(roomRule),
            "roomRuleList.$.ruleName": ruleName,
            "roomRuleList.$.gameType": gameType
        };
        let data = await commonDao.findOneAndUpdate('unionModel', { unionID: this.unionID, "roomRuleList._id": _id }, info);
        let roomRuleList = [];
        let curRule = null;
        for (let i = 0; i < data.roomRuleList.length; ++i) {

            let detail = data.roomRuleList[i]._doc;
            roomRuleList.push(detail);
            if (detail._id == _id) {
                curRule = detail;
            }
        }
        this.unionData.roomRuleList = roomRuleList;

        //如果修改了房间规则 需要删除没人的桌子
        await this.deleteEmptyRoom();

        return curRule;
    }


    async deleteEmptyRoom() {

        for (let key in this.roomList) {
            if (this.roomList.hasOwnProperty(key)) {

                if (!this.roomList[key]) {
                    delete this.roomList[key];
                    continue;
                }
                let roomInfo = this.roomList[key].getRoomInfo();
                if (roomInfo.roomUserInfoArr.length == 0) {
                    await this.dismissRoom(key);
                }
            }
        }
    }


    // 删除房间规则
    async removeRoomRuleList(ruleID) {
        if (!this.unionData) {
            throw new Error(code.FAIL);
        }
        let data = await commonDao.findOneAndUpdate('unionModel', { unionID: this.unionID }, { $pull: { roomRuleList: { _id: ruleID } } });
        let roomRuleList = [];
        for (let i = 0; i < data.roomRuleList.length; ++i) {
            roomRuleList.push(data.roomRuleList[i]._doc);
        }
        this.unionData.roomRuleList = roomRuleList;
    }

    async dismissRoom(roomID) {
        let room = this.roomList[roomID];
        if (!room) return false;
        await room.dismissRoom(enumeration.gameRoomDismissReason.UNION_OWNER_DISMISS).catch(e => { logger.error(e.stack) });
        return true;
    }


    /************************* 房间相关接口 **************************/

    async kickUser(uid, roomID) {
        let room = this.roomList[roomID];
        if (room) {
            await room.kickUser(uid);
        }
        return code.OK;
    }


    async userLeaveRoom(uid, roomID) {
        let room = this.roomList[roomID];
        if (room) {
            //  await room.userLeaveRoomByAgain(uid);
            return await room.userAskLeaveRoom(uid, true);
        }
    }

    async robotReady(uid, roomID) {

        if (!roomID) {
            let robotUser = await commonDao.findOneData('userModel', { 'uid': uid });
            roomID = robotUser.roomID;
        }

        let room = this.roomList[roomID];
        if (room) {


            let userInfo = room.userArr[uid];
            //在座位上
            if (userInfo && userInfo.chairID < room.chairCount) {
                if (room.curBureau >= 1) {
                    return 0; //游戏已经开始了 不准备
                } else {
                    return await room.userReady(uid);
                }

            } else {
                //不在座位上？
                let curChairID = userInfo.chairID;
                let chairID = 0;
                for (let key in room.userArr) {
                    if (room.userArr.hasOwnProperty(key)) {
                        if (room.userArr[key].chairID < room.chairCount) {
                            chairID += 1;
                        }
                    }
                }
                if (chairID < room.chairCount) {
                    //旁观坐下
                    return await room.userChangeSeat(uid, curChairID, chairID);
                } else {
                    return code.FAIL;
                }

            }
        } else {
            return code.FAIL;
        }
    }

    // 创建房间
    async createRoom(ruleID, gameRule, userInfo, createAndWatch, gameType) {


        logger = logerService.getLogByType(gameType);

        // 俱乐部房间，则判断该玩家是否在该俱乐部
        if (this.unionID !== 1) {
            if (!this.unionData.opening) {
                return code.PERMISSION_NOT_ENOUGH;
            }
            let item = userInfo.unionInfo.find(function (ele) {
                return ele.unionID === this.unionID;
            }.bind(this));
            if (!item) return code.INVALID_UERS;
        }

        //判断是否可以空桌
        if (this.unionID !== 1 && this.unionData.emptyTable) {
            //判断是否有同类型桌子
            for (let roomID in this.roomList) {
                let roomData = this.roomList[roomID];
                if (roomData.gameRule._id == ruleID) {
                    return code.ROOM_ALREAY_LIMIT;
                }
            }
        }



        //创建-进入游戏-快速进入不能同时操作
        let userID = userInfo.uid;
        let lockKey = userID + '-create-join-room';
        let isLocked = redisService.isLocked(lockKey, 2);

        let ruleKey = ruleID + 'creatRoom';
        let ruleKeyLocked = redisService.isLocked(ruleKey, 2);




        logger.info(`[${userInfo.uid}] union create room begin isLocked = ${isLocked}  ruleKeyLocked = ${ruleKeyLocked}`);

        if (this.unionID !== 1 && this.unionData.emptyTable && ruleKeyLocked) {
            return code.ROOM_ALREAY_LIMIT;
        }

        if (isLocked) {
            return code.USER_DATA_LOCKED;
        }

        //获取游戏规则
        this.activeTime = Date.now();
        if (!!ruleID) {
            let roomRuleItem = null;
            for (let i = 0; i < this.unionData.roomRuleList.length; ++i) {
                if (this.unionData.roomRuleList[i]._id.toString() === ruleID) {
                    roomRuleItem = this.unionData.roomRuleList[i];
                    break;
                }
            }
            if (!roomRuleItem) {

                redisService.unLock(ruleKey);
                redisService.unLock(lockKey);
                return code.ROOM_NOT_EXIST;
            }
            gameRule = JSON.parse(roomRuleItem.gameRule);
            gameRule.gameType = roomRuleItem.gameType;
            gameRule.ruleName = roomRuleItem.ruleName;
            gameRule._id = roomRuleItem._id.toString();
        }

        //判断盟主房费是否足够
        // if (this.unionID !== 1 && gameRule.payType === enumeration.roomPayType.WOZHIFU) {
        //     let payDiamond = gameConfig.oneUserDiamondCount(gameRule.bureau, gameRule.gameType);
        //     let userData = await userDao.getUserDataByUid(this.unionData.ownerUid);
        //     if (userData.gold <= 0 || userData.gold < payDiamond) {
        //         redisService.unLock(ruleKey);
        //         redisService.unLock(lockKey);
        //         return code.NOT_ENOUGH_GOLD;
        //     }
        // } 

        //非联盟放假
        if (this.unionID == 1) {
            let isGoldEnough = await gameDataServices.checkGold(userInfo, gameRule);
            if (isGoldEnough) {
                redisService.unLock(ruleKey);
                redisService.unLock(lockKey);
                return code.NOT_ENOUGH_GOLD;
            }
        }

        // 创建房间ID
        let roomID = unionManager.createNewRoomID();
        let creatorInfo = null;
        if (this.unionID === 1) {
            creatorInfo = {
                creatorType: enumeration.roomCreatorType.USER_CREATE,
                uid: userInfo.uid
            }
        } else {
            creatorInfo = {
                creatorType: enumeration.roomCreatorType.UNION_CREATE,
                unionID: this.unionID,
                unionType: this.unionData.unionType,
                unionGameType: this.unionData.unionGameType,
                ownerUid: this.unionData.ownerUid,
                serverScore: this.unionData.serverScore || 0,
                pumpWaterPattern: this.unionData.pumpWaterPattern || false
            };
        }

        //创建房间对象
        let roomFrame = null;
        gameRule.createAndWatch = createAndWatch;
        let newGameFrame = gameConfig.getGameFrameByType(gameRule.gameType);
        if (newGameFrame) {
            //新框架
            let gameFrame = require('../../../gameComponent/' + newGameFrame.gameFrameSinkPath);
            roomFrame = new gameFrame(roomID, creatorInfo, gameRule);
        }
        else {
            //之前的游戏走老框架
            roomFrame = new RoomFrame(roomID, creatorInfo, gameRule);
        }

        let resCode = code.FAIL;
        if (gameRule.createAndWatch) {
            //此类型创建的房间进入必须旁观
            resCode = await roomFrame.userJoinWatch(userInfo);
        } else {
            //其他类型房间直接进入并坐下
            resCode = await roomFrame.userEntryRoom(userInfo);
        }
        this.roomList[roomID] = roomFrame;
        logger.info(`[${userInfo.uid}] create room end and join room = [${roomID}] createAndWatch = ${gameRule.createAndWatch} resCode = ${resCode} `);
        if (resCode != code.OK) {
            logger.info(`[${userInfo.uid}] join room fail and delete room = ${roomID} `);
            this.dismissRoom(roomID);
        }
        redisService.unLock(ruleKey);
        redisService.unLock(lockKey);
        return resCode;
    }

    // 加入房间
    async joinRoom(roomID, userInfo) {

        //  logger.info(`-------------[进入房间开始]------------------`);
        // 俱乐部房间，则判断该玩家是否在该俱乐部
        if (this.unionID !== 1) {
            let item = userInfo.unionInfo.find(function (ele) {
                return ele.unionID === this.unionID;
            }.bind(this));
            if (!item && !userInfo.isRobot) return code.NOT_IN_UNION;
        }

        //创建-进入游戏-快速进入不能同时操作
        let userID = userInfo.uid;
        let lockKey = userID + '-create-join-room';
        let isLocked = redisService.isLocked(lockKey, 2);
        if (isLocked) return code.ROOM_JOIN_BUSY_LIMIT;

        this.activeTime = Date.now();
        let roomFrame = this.roomList[roomID];
        if (!roomFrame) {
            redisService.unLock(lockKey);
            return code.ROOM_NOT_EXIST;
        } else {
            let enterCode = await roomFrame.userEntryRoom(userInfo);
            redisService.unLock(lockKey);
            return enterCode;
        }

    }

    // 加入旁观
    async joinWatch(roomID, userInfo) {

        let userID = userInfo.uid;
        let lockKey = userID + '-join-watch';
        let isLocked = redisService.isLocked(lockKey, 2);

        if (isLocked) {
            logger.info(`[${userInfo.uid}] union join room watch isLocked = ${isLocked} `);
            return code.OK;
        }

        //判断是否在联盟中
        if (this.unionID !== 1) {
            let item = userInfo.unionInfo.find(function (ele) {
                return ele.unionID === this.unionID;
            }.bind(this));
            if (!item && !userInfo.isRobot) return code.NOT_IN_UNION;
        }

        this.activeTime = Date.now();
        let roomFrame = this.roomList[roomID];
        if (!roomFrame) {
            return code.ROOM_NOT_EXIST;
        } else {
            let enterCode = await roomFrame.userJoinWatch(userInfo);
            return enterCode;
        }
    }


    async quickJoin(ruleID, userInfo) {


        //创建-进入游戏-快速进入不能同时操作
        let userID = userInfo.uid;
        let lockKey = userID + '-create-join-room';
        let isLocked = redisService.isLocked(lockKey, 3);
        if (isLocked) return;

        this.activeTime = Date.now();
        let roomRuleItem = null;
        for (let i = 0; i < this.unionData.roomRuleList.length; ++i) {
            if (this.unionData.roomRuleList[i]._id.toString() === ruleID) {
                roomRuleItem = this.unionData.roomRuleList[i];
                break;
            }
        }
        if (!roomRuleItem) {
            redisService.unLock(lockKey);
            return code.ROOM_NOT_EXIST;
        }

        // 如果有现有房间则直接
        for (let key in this.roomList) {
            if (this.roomList.hasOwnProperty(key)) {
                let room = this.roomList[key];
                if (!room.hasStartedOneBureau && !room.roomDismissed && room.gameRule._id === ruleID && room.canEnter() && room.hasEmptyChair()) {
                    redisService.unLock(lockKey);
                    return await this.joinRoom(room.roomID, userInfo);
                }
            }
        }

        // 创建房间
        let roomID = unionManager.createNewRoomID();
        let creatorInfo = null;
        if (this.unionID === 1) {
            creatorInfo = {
                creatorType: enumeration.roomCreatorType.USER_CREATE,
                uid: userInfo.uid
            }
        } else {
            creatorInfo = {
                creatorType: enumeration.roomCreatorType.UNION_CREATE,
                unionID: this.unionID
            };
        }
        let gameRule = JSON.parse(roomRuleItem.gameRule);
        gameRule.gameType = roomRuleItem.gameType;
        gameRule.ruleName = roomRuleItem.ruleName;
        gameRule._id = roomRuleItem._id.toString();
        let roomFrame = new RoomFrame(roomID, creatorInfo, gameRule);
        this.roomList[roomID] = roomFrame;
        roomFrame.updateLotteryInfo(this.getLotteryStatus());
        redisService.unLock(lockKey);
        return await roomFrame.userEntryRoom(userInfo);
    }

    // 销毁房间
    destroyRoom(roomID) {
        delete this.roomList[roomID];
    }

    // 获取房间
    getRoomByID(roomID) {
        return this.roomList[roomID];
    }

    isOpening() {
        return !!this.unionData && this.unionData.opening;
    }

    // 获取上次活跃时间
    getLastActiveTime() {
        return this.activeTime;
    }

    isShouldDelete(time) {
        return (utils.getLength(this.roomList) === 0 && this.activeTime - Date.now() > time)
    }

    dailyClear() {
        if (!this.unionData) return;
        if (!!this.unionData.hongBaoInfo) {
            if (this.unionData.hongBaoInfo.hongBaoScoreList.length !== 0 || this.unionData.hongBaoInfo.hongBaoUidList.length !== 0) {
                this.unionData.hongBaoInfo.hongBaoScoreList = [];
                this.unionData.hongBaoInfo.hongBaoUidList = [];

            }
            commonDao.updateData('unionModel', { unionID: this.unionID }, { hongBaoUidList: [], hongBaoScoreList: [] }).catch(e => { logger.error(e.stack) });
        }
    }

    /*-------------------------------预制普通房间-------------------------------------------------*/

    async createRoomAuto(ruleID, gameRule, userInfo) {


        // 俱乐部房间
        if (this.unionID !== 1) {
            if (!this.unionData.opening) return code.PERMISSION_NOT_ENOUGH;
            let item = userInfo.unionInfo.find(item => item.unionID == this.unionID);
            if (!item) return code.INVALID_UERS;
            if (!item.isManager && userInfo.uid != this.unionData.ownerUid) {
                return code.PERMISSION_NOT_ENOUGH;
            }
        }

        //获取游戏规则
        this.activeTime = Date.now();
        if (!!ruleID) {
            let roomRuleItem = this.unionData.roomRuleList.find(item => item._id == ruleID);
            if (!roomRuleItem) {
                return code.ROOM_NOT_EXIST;
            }
            gameRule = JSON.parse(roomRuleItem.gameRule);
            gameRule.gameType = roomRuleItem.gameType;
            gameRule.ruleName = roomRuleItem.ruleName;
            gameRule._id = roomRuleItem._id.toString();
        }
        let logger = logerService.getLogByType(gameRule.gameType);
        // 创建房间ID
        let roomID = unionManager.createNewRoomID();
        let creatorInfo = null;
        if (this.unionID === 1) {
            creatorInfo = { ruleID, roomType: enumeration.roomType.HUNDRED, creatorType: enumeration.roomCreatorType.USER_CREATE, uid: userInfo.uid }
        } else {
            creatorInfo = {
                ruleID: ruleID,
                roomType: enumeration.roomType.HUNDRED,
                creatorType: enumeration.roomCreatorType.UNION_CREATE,
                unionID: this.unionID,
                unionType: this.unionData.unionType,
                unionGameType: this.unionData.unionGameType,
                ownerUid: this.unionData.ownerUid,
                serverScore: this.unionData.serverScore || 0,
                pumpWaterPattern: this.unionData.pumpWaterPattern || false
            };
        }

        //创建房间对象
        let roomFrame = null;

        let newGameFrame = gameConfig.getGameFrameByType(gameRule.gameType);
        if (newGameFrame) {
            //新框架
            let gameFrame = require('../../../gameComponent/' + newGameFrame.gameFrameSinkPath);
            roomFrame = new gameFrame(roomID, creatorInfo, gameRule);
        } else {
            //之前的游戏走老框架
            roomFrame = new RoomFrame(roomID, creatorInfo, gameRule);
        }

        let resCode = code.OK;
        this.roomList[roomID] = roomFrame;
        logger.info(`[${this.unionID}][${userInfo.uid}] union create auto room sucess `);
        if (this.unionID == 1) {
            //大厅的时候加入游戏
            resCode = await roomFrame.userEntryRoom(userInfo);
        }
        return resCode;
    }



    async getGameRuleByID(uniqueID) {

        let curGame = goldGame.find(item => item.codeList.includes(uniqueID));
        let gameRule = null;
        if (curGame) {
            gameRule = curGame.gameRule;
            let curDetail = curGame.roomList.find(item => item.uniqueID == uniqueID);
            if (curDetail) {
                gameRule.baseScore = curDetail.baseScore;
                gameRule.scoreLowLimit = curDetail.minScore;
                gameRule.scoreDismissLimit = curDetail.baseScore;
                gameRule.payType = enumeration.roomPayType.GOLD;
                gameRule.uniqueID = uniqueID;
            }
        }
        return JSON.parse(JSON.stringify(gameRule));
    }



    //创建金币场游戏
    async createRoomGD(uniqueID, userInfo) {

        // 俱乐部房间
        if (this.unionID !== 1) {
            return code.PERMISSION_NOT_ENOUGH;
        }
        //获取游戏规则
        this.activeTime = Date.now();
        let gameRule = await this.getGameRuleByID(uniqueID);
        if (!gameRule) {
            return code.PERMISSION_NOT_ENOUGH;
        }

        if (userInfo.score < gameRule.scoreLowLimit) {
            return code.NOT_ENOUGH_SCORE;
        }

        let logger = logerService.getLogByType(gameRule.gameType);
        // 创建房间ID
        let roomID = unionManager.createNewRoomID();
        let creatorInfo = { roomType: enumeration.roomType.GOLD, creatorType: enumeration.roomCreatorType.USER_CREATE, uid: userInfo.uid }

        //创建房间对象
        let roomFrame = null;

        let newGameFrame = gameConfig.getGameFrameByType(gameRule.gameType);
        if (newGameFrame) {
            //新框架
            let gameFrame = require('../../../gameComponent/' + newGameFrame.gameFrameSinkPath);
            roomFrame = new gameFrame(roomID, creatorInfo, gameRule);
        }

        let resCode = code.OK;
        this.roomList[roomID] = roomFrame;
        logger.info(`[${userInfo.uid}] union create gold room success `);
        if (this.unionID == 1) {
            //大厅的时候加入游戏
            resCode = await roomFrame.userEntryRoom(userInfo);
        }
        return resCode;
    }

}
module.exports = union;
